#!/usr/bin/env python  
# -*- coding: utf-8 -*-  

#
#   Very simple python FUSE memory file system
#
#
#
#   Mostly Complete, Working
#   ToDo: filesystem stats, keep file/dir metadata
#


import errno  
import fuse  
import stat  
import time  
import os
  
fuse.fuse_python_api = (0, 2)  
  
class MyFS(fuse.Fuse):  
    def __init__(self, *args, **kw):  
        fuse.Fuse.__init__(self, *args, **kw)  
        self.stuff=dict()
        self.addDir("/")
        self.fd=0
        self.log_level=4

    def findPath(self, path):
        path = path.split("/")
        path[0] = "/"
        follow=self.dirs
        for i in range(0,len(path)):
            if path[i]=="":
                continue
            if path[i] not in follow:
                return -errno.ENOENT
            follow=follow[path[i]]
        return follow

    def addFile(self, path):
        self.stuff[path]=dict() 
        self.stuff[path]['st']=fuse.Stat()
        self.stuff[path]['st']=fuse.Stat()
        self.stuff[path]['st'].st_mode = stat.S_IFREG | 0777
        self.stuff[path]['st'].st_nlink = 1
        self.stuff[path]['st'].st_atime = int(time.time())
        self.stuff[path]['st'].st_mtime = int(time.time())
        self.stuff[path]['st'].st_ctime = int(time.time())
        self.stuff[path]['st'].st_size = 0
        self.stuff[path]['data']=bytearray()


    def addDir(self, path):
        self.stuff[path]=dict() 
        self.stuff[path]['st']=fuse.Stat()
        self.stuff[path]['st'].st_mode = stat.S_IFDIR | 0777
        self.stuff[path]['st'].st_nlink = 2
        self.stuff[path]['st'].st_atime = int(time.time())
        self.stuff[path]['st'].st_mtime = int(time.time())
        self.stuff[path]['st'].st_ctime = int(time.time())

         

    def getattr(self, path):  
        if path in self.stuff:
            return self.stuff[path]['st']
        return -errno.ENOENT

    def readdir(self, path, offset):  
        send=['.','..']
        for i in self.stuff:
            if i[:len(path)].count(path) > 0:
                lenPath= len(path)
                if path == "/":
                    lenPath=0
                if i[lenPath+1:].count("/") <=0 and len(i[lenPath+1:])>0:
                    send.append(i[lenPath+1:])
        for x in send:
            yield fuse.Direntry(x)

    def mkdir(self, path, mode):
        return self.addDir(path)

    def rmdir(self, path):
        tmp = list()
        for i in self.stuff:
            tmp.append(i[:len(path)])
        if i.count(path) > 1:
            return -errno.ENOTEMPTY
        del self.stuff[path]

    def unlink(self, path):
        del self.stuff[path]
        
    def mknod(self, path, mode, dev):
        rt = self.addFile(path)
        return 0

    def open(self, path, flags):
        return 0

    def utimens(self, path, tmp, tmp2):
        return 0

    def read(self, path, size, offset):
        if path in self.stuff:
            return self.stuff[path]['data'][offset:offset + size]
        return -errno.ENOENT

    def write(self, path, data, offset):
        if path in self.stuff:
            if len(self.stuff[path]['data']) == offset:
                self.stuff[path]['data'].extend(bytearray(data))
            else:
                self.stuff[path]['data'][offset:offset + len(data)] = data
        self.stuff[path]['st'].st_size=len(self.stuff[path]['data'])
        return len(data)

    def truncate(self, path, length):
        if path in self.stuff:
            if length < len(self.stuff[path]['data']):
                self.stuff[path]['data']=self.stuff[path]['data'][:length]
        
        
        
        
      
if __name__ == '__main__':  
    fs = MyFS()  
    fs.parse(errex=1)  
    fs.main()  
